#include <QMessageBox>
#include <QInputDialog>
#include <QMouseEvent>
#include <QPainter>
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "../../board/Board.h"
#include "../../checkers/Checkers.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    gameType = NO_GAME;
    playerTurn = CHECKERS_PLAYER1;
    clicked = CHECKERS_EMPTY;

    sqWidth = this->width() / 8;
    sqHeight = this->height() / 8;

    x = y = NULL_MOUSE;
    prevx = prevy = NULL_MOUSE;
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_actionQuit_triggered()
{
    this->closeEvent();
}

void MainWindow::on_actionAbout_triggered()
{
    QMessageBox msgBox;
    msgBox.setText("About BSOD checkers");
    msgBox.setInformativeText("BSOD checkers copyright 2011 \n\nAlan Mattila, Ken Cramer, Curtis Parks, Manoj Ravikumar");
    msgBox.setStandardButtons(QMessageBox::Ok);
    msgBox.setDefaultButton(QMessageBox::Ok);
    msgBox.exec();
}

void MainWindow::on_actionNew_Local_Game_triggered()
{
    QMessageBox msgBox, msgBox2;
    msgBox.setText("What type of local game?");
    QPushButton *twoPlayerButton = msgBox.addButton(tr("Two Player"), QMessageBox::YesRole);
    QPushButton *aiButton = msgBox.addButton(tr("vs AI"), QMessageBox::NoRole);
    QPushButton *cancelButton = msgBox.addButton(QMessageBox::Cancel);

    msgBox2.setText("AI difficulty?");
    QPushButton *easyButton = msgBox2.addButton(tr("Easy"), QMessageBox::AcceptRole);
    QPushButton *mediumButton = msgBox2.addButton(tr("Medium"), QMessageBox::NoRole);
    QPushButton *hardButton = msgBox2.addButton(tr("Hard"), QMessageBox::YesRole);

    msgBox.exec();

    if(msgBox.clickedButton() == (QAbstractButton*) twoPlayerButton)
    {
        gameType = LOCAL_2PLAYER;
        playerTurn = CHECKERS_PLAYER1;
    }
    else if(msgBox.clickedButton() == (QAbstractButton*) aiButton)
    {
        msgBox2.exec();

        if(msgBox2.clickedButton() == (QAbstractButton*) easyButton)
        {
            aiLevel = EASY;
        }
        else if(msgBox.clickedButton() == (QAbstractButton*) mediumButton)
        {
            aiLevel = MEDIUM;
        }
        else if(msgBox.clickedButton() == (QAbstractButton*) hardButton)
        {
            aiLevel = HARD;
        }

        gameType = LOCAL_AI;
    }
    else if (msgBox.clickedButton() == (QAbstractButton*) cancelButton)
    {
        return;
    }
}

void MainWindow::on_actionHost_Network_Game_triggered()
{
    QMessageBox msgBox;

    msgBox.setText("waiting for connection");
    msgBox.setStandardButtons(QMessageBox::Cancel);

    if(msgBox.exec() == QMessageBox::Cancel)
    {
        return;
    }
    else
    {
        //do whatever we need to do to init the network game
    }
}

void MainWindow::on_actionConnect_to_Game_triggered()
{
    //QInputDialog inputBox;

    bool ok;
    QString text = QInputDialog::getText(this, tr("Host IP address"),
                                              tr("IP address:"), QLineEdit::Normal,
                                              tr("192.168.0.1"), &ok);
    if (ok && !text.isEmpty())
    {
        //do networky stuff, including validaing inputs
    }
}

void MainWindow::on_actionHow_to_Play_triggered()
{
    QMessageBox msgBox;
    msgBox.setText("How to play checkers:\n\n"
                   "players take turns moving their pieces diagonally 1 diagonal space at a time.\n"
                   "The goal of the game is to capture all of your opponents pieces.\n"
                   "To capturea  piece, you must \"jump\" it - that is if an opponents\n"
                   "piece is diagonally adjacent to your own with an open space on the other side\n"
                   "you may jump over it and then remove that piece from the board.\n\n"
                   "at first pieces may only move in the direction of the opponents side of the board.\n"
                   "should a piece reach the other side of the board, it becomes a \"king\" and may then\n"
                   "move backwards."
                   "if no captures are made within 50 moves, the game is declared a draw.");

    msgBox.exec();
}

void MainWindow::setBoardState(Board myboard)
{
    //possibly unused stub, leaving it in because it might be useful for network games
    //board.operator =(myboard);
}

void MainWindow::closeEvent()
{
    QMessageBox msgBox;
    msgBox.setText("Do you really want to quit?");
    msgBox.setIcon(QMessageBox::Question);
    msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);

    int ret = msgBox.exec();

    if( ret == QMessageBox::Yes )
    {
        this->close();
    }
}

void MainWindow::paintEvent(QPaintEvent *event)
{

    QPainter square(this);

    QBrush black(Qt::black, Qt::SolidPattern);
    QBrush white(Qt::white, Qt::SolidPattern);
    QBrush red(Qt::red, Qt::SolidPattern);
    QBrush yellow(Qt::yellow, Qt::SolidPattern);
    QBrush blue(Qt::blue, Qt::SolidPattern);
    QPen redPen(red, 5);
    QPen yellowPen(yellow, 10);
    QPen bluePen(blue, 5);

    square.setFont(QFont("Courier", 30, QFont::Bold));


    //in case board size has changed
    sqWidth = this->width() / 8;
    sqHeight = this->height() / 8;


    //draw the board
    for(int i = 0; i < 8; i++)
    {
        for(int j = 0; j < 8; j++)
        {
            if((i % 2 == 0 && j % 2 == 0 ) || (i % 2 != 0 && j % 2 != 0))
            {
                square.fillRect(i*sqWidth, j*sqHeight, sqWidth, sqHeight, white);
            }
            else
            {
                square.fillRect(i*sqWidth, j*sqHeight, sqWidth, sqHeight, black);
            }
        }
    }

    //draw the pieces
    for(int i = 0; i < 8; i++)
    {
        for(int j = 0; j < 8; j++)
        {
            switch(game.GetBoard()->GetValue(i, j))
            {
            case CHECKERS_PLAYER1:
                square.setBrush(red);
                square.setPen(redPen);
                square.drawEllipse(i*sqWidth, j*sqHeight, sqWidth, sqHeight);
            break;
            case CHECKERS_PLAYER1_KING:
                square.setBrush(red);
                square.setPen(redPen);
                square.drawEllipse(i*sqWidth, j*sqHeight, sqWidth, sqHeight);
                square.setPen(yellowPen);
                square.drawText(i*sqWidth + (sqWidth/3), j*sqHeight + (sqHeight*2/3),tr("K"));
            break;
            case CHECKERS_PLAYER2:
                square.setBrush(blue);
                square.setPen(bluePen);
                square.drawEllipse(i*sqWidth, j*sqHeight, sqWidth, sqHeight);
            break;
            case CHECKERS_PLAYER2_KING:
                square.setBrush(blue);
                square.setPen(bluePen);
                square.drawEllipse(i*sqWidth, j*sqHeight, sqWidth, sqHeight);
                square.setPen(yellowPen);
                square.drawText(i*sqWidth + (sqWidth/3), j*sqHeight + (sqHeight*2/3),tr("K"));
            break;
            }
        }
    }

    //draw "select piece"
    if(clicked != CHECKERS_EMPTY)
    {
        switch(playerTurn)
        {
        case CHECKERS_PLAYER1:
            if(game.GetBoard()->GetValue(x, y) == CHECKERS_PLAYER1)
            {
                square.setBrush(red);
                square.setPen(yellowPen);
                square.drawEllipse(x*sqWidth, y*sqHeight, sqWidth, sqHeight);
            }
            else if(game.GetBoard()->GetValue(x, y) == CHECKERS_PLAYER1_KING)
            {
                square.setBrush(red);
                square.setPen(yellowPen);
                square.drawEllipse(x*sqWidth, y*sqHeight, sqWidth, sqHeight);
                square.drawText(x*sqWidth + (sqWidth/3), y*sqHeight + (sqHeight*2/3),tr("K"));
            }
        break;
        case CHECKERS_PLAYER2:
            if(game.GetBoard()->GetValue(x, y) == CHECKERS_PLAYER2)
            {
                square.setBrush(blue);
                square.setPen(yellowPen);
                square.drawEllipse(x*sqWidth, y*sqHeight, sqWidth, sqHeight);
            }
            else if(game.GetBoard()->GetValue(x, y) == CHECKERS_PLAYER2_KING)
            {
                square.setBrush(blue);
                square.setPen(yellowPen);
                square.drawEllipse(x*sqWidth, y*sqHeight, sqWidth, sqHeight);
                square.drawText(x*sqWidth + (sqWidth/3), y*sqHeight + (sqHeight*2/3),tr("K"));
            }
        break;
        }
        clicked = CHECKERS_EMPTY;
    }
}

void MainWindow::mousePressEvent( QMouseEvent *e )
{
    //get the co-ords of the square which has been clicked
    x = (e->x() - (e->x() % sqWidth)) / sqWidth;
    y = (e->y() - (e->y() % sqHeight)) / sqHeight;
    int selPiece = game.GetBoard()->GetValue(x, y);


    if(game.GetStatus() == STATUS_IN_PROGRESS)
    {
        switch(gameType)
        {
        case LOCAL_2PLAYER:
            //if this is to select the piece which is to be moved
            if(prevx == NULL_MOUSE && prevy == NULL_MOUSE)
            {
                //-2 in case the selected piece is a king, this line ensures the piece is one of a player's own
                if(selPiece == playerTurn || (selPiece-2) == playerTurn)
                {
                    prevx = x;
                    prevy = y;
                    clicked = playerTurn;
                    break;
                }
            }
            else
            {
                if(game.FindPathForMove(prevx, prevy, x, y))
                {
                    game.Move(prevx, prevy, x, y);
                    playerTurn = (playerTurn == CHECKERS_PLAYER1) ? CHECKERS_PLAYER2 : CHECKERS_PLAYER1;
                }

                //whether we make the move or not, forget hte previous mouse location
                prevx = prevy = NULL_MOUSE;
            }
        break;

        case LOCAL_AI:
        break;

        case NETWORK_HOST:

        case NETWORK_CLIENT:
        break;

        case NO_GAME:
            //this will trigger after game is over, or before game is started.
            return;
        break;
        }
    }


    //at this point, we should be able to safely redraw the screen.
    this->repaint();

}


